<?php

namespace application\middleware;

use fastphp\Middleware;
use fastphp\Request;
use fastphp\Response;
use fastphp\facade\Config;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Firebase\JWT\SignatureInvalidException;
use Firebase\JWT\BeforeValidException;
use Firebase\JWT\ExpiredException;
use DomainException;
use InvalidArgumentException;
use UnexpectedValueException;

/**
 * JWT认证中间件
 * 验证请求中的JWT令牌
 */
class JwtAuth implements Middleware
{
    /**
     * @inheritDoc
     */
    public function handle(Request $request, Response $response, callable $next)
    {
        // 获取Authorization头
        $authHeader = $request->header('Authorization');

        if (!$authHeader || strpos($authHeader, 'Bearer ') !== 0) {
            $response->status(401);
            return $response->json([
                'code' => 401,
                'message' => '未提供有效的令牌'
            ]);
        }

        // 提取token
        $token = substr($authHeader, 7);
        $jwtConfig = Config::get('jwt');

        try {
            // 验证token
            $decoded = JWT::decode($token, new Key($jwtConfig['secret'], $jwtConfig['algorithm']));

            // 将用户信息存入请求对象
            $request->setAttribute('user', $decoded);

        } catch (ExpiredException $e) {
            $response->status(401);
            return $response->json([
                'code' => 401,
                'message' => '令牌已过期'
            ]);
        } catch (SignatureInvalidException $e) {
            $response->status(401);
            return $response->json([
                'code' => 401,
                'message' => '无效的令牌签名'
            ]);
        } catch (BeforeValidException $e) {
            $response->status(401);
            return $response->json([
                'code' => 401,
                'message' => '令牌尚未生效'
            ]);
        } catch (InvalidArgumentException | DomainException | UnexpectedValueException $e) {
            $response->status(401);
            return $response->json([
                'code' => 401,
                'message' => '无效的令牌格式'
            ]);
        }

        // 令牌验证通过，继续处理请求
        return $next($request, $response);
    }
}